package com.honvay.cola.cloud.auth.controller;

import com.honvay.cola.cloud.framework.core.constant.ErrorStatus;
import com.honvay.cola.cloud.framework.core.protocol.Result;
import com.honvay.cola.cloud.framework.security.userdetail.User;
import com.honvay.cola.cloud.vcc.client.VerificationCodeClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @author LIQIU
 * @date 2018-3-8
 **/
@RestController
@Api(tags = "认证接口")
public class AuthController {


    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @Autowired
    @Qualifier("consumerTokenServices")
    private ConsumerTokenServices consumerTokenServices;

    @Autowired
    private VerificationCodeClient verificationCodeClient;

    @GetMapping("/current")
    @ApiOperation("获取当前用户信息")
    public Result<User> getUser(Principal principal) {
        if (null != principal) {
            if (principal instanceof OAuth2Authentication) {
                OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) principal;
                Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
                if (null != userAuthentication) {
                    User user = (User) userAuthentication.getPrincipal();
                    return Result.buildSuccess(user);
                }
            }
        }
        return Result.buildFailure(ErrorStatus.INTERNAL_SERVER_ERROR);

    }


    @PostMapping("/sms/token")
    @ApiOperation("获取短信登录Token")
    public Result<String> getToken(String phoneNumber) {
        return verificationCodeClient.getToken(6, null, "0", phoneNumber, true);
    }


    @ApiOperation(value = "pc后台管理管账号密码登录", notes = "账号密码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "username", defaultValue = "admin", value = "用户名登陆",  dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "password", defaultValue = "111111", value = "用户密码",required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "grant_type", defaultValue = "password", value = "oauth2鉴权类型密码模式",required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "scope", defaultValue = "ui", value = "鉴权范围",required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "client_id", defaultValue = "browser",value = "鉴权客服端", required = true, dataType = "String"),
    })
    @RequestMapping(value = "/sysLogin", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public Result<OAuth2AccessToken> sysLogin(@RequestParam("username") String username,
                                              @RequestParam("password") String password,
                                              @RequestParam("grant_type") String grantType,
                                              @RequestParam("scope") String scope,
                                              @RequestParam("client_id") String clientId
    ) {
        Map<String, String> parameters = new HashMap<>();
        try {
            logger.info("login  start ......");
//            parameters.put("grant_type", "password");//设置授权类型为密码模式
//            parameters.put("scope", "ui");
//            parameters.put("client_id", "browser");
            parameters.put("username", username);
            parameters.put("password", password);
            parameters.put("grant_type", grantType);//设置授权类型为密码模式
            parameters.put("scope", scope);
            parameters.put("client_id", clientId);
            Collection<GrantedAuthority> grantedAuthorities = new HashSet<>();
//            grantedAuthorities.add(new SimpleGrantedAuthority("admin"));//此处不能为空
            Authentication authentication = new UsernamePasswordAuthenticationToken("browser", "", grantedAuthorities);
            ResponseEntity<OAuth2AccessToken> responseEntity = tokenEndpoint.postAccessToken(authentication, parameters);
            logger.info("login  end ......");
            return Result.buildSuccess(responseEntity.getBody());
        } catch (InvalidGrantException e) {
            logger.error("login error  用户名密码不正确 ....", e);
            return Result.buildFailure("用户名密码不正确");
        } catch (Exception e) {
            logger.error("login error ....", e);
            return Result.buildFailure(e.getMessage());
        }
    }


    @ApiOperation(value = "pc后台管理管账号登出接口", notes = "pc后台管理管账号登出接口")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "accessToken", value = "accessToken值", required = true, dataType = "String"),
    })
    @RequestMapping(value = "/sysLogout", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
//    @RequestMapping(value = "/sysLogout", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public Result<String> sysLogout(@RequestParam("accessToken") String accessToken) {
        try {
            logger.info("logout  start ......");
            consumerTokenServices.revokeToken(accessToken);
            logger.info("logout  end ......");
            return Result.buildSuccess("退出登录成功");
        } catch (Exception e) {
            logger.error("logout error ....", e);
            return Result.buildFailure(e.getMessage());
        }
    }





}
